package cn.smile.business.core.impl;

import cn.smile.bean.dto.basic.BasicItemCountDTO;
import cn.smile.bean.dto.basic.DicInfoDTO;
import cn.smile.bean.dto.basic.MyShopDTO;
import cn.smile.bean.dto.core.*;
import cn.smile.bean.entity.core.SysUser;
import cn.smile.bean.form.core.role.RoleQueryForm;
import cn.smile.bean.form.core.user.*;
import cn.smile.bean.form.login.LoginInfoForm;
import cn.smile.business.basic.IBillBasicItemService;
import cn.smile.business.basic.IDicInfoService;
import cn.smile.business.basic.IMyShopService;
import cn.smile.business.core.IRoleService;
import cn.smile.business.core.ISysUserService;
import cn.smile.business.msg.IEmailInfoService;
import cn.smile.commons.constant.*;
import cn.smile.commons.domain.BaseServiceImpl;
import cn.smile.commons.enums.basic.PredefinedDicEnum;
import cn.smile.commons.enums.core.UserSexEnum;
import cn.smile.commons.enums.core.UserStatusEnum;
import cn.smile.commons.enums.core.UserTypeEnum;
import cn.smile.commons.enums.msg.MailCodeEnum;
import cn.smile.commons.exceptions.BusinessException;
import cn.smile.commons.response.MyResponseCode;
import cn.smile.repository.core.SysUserMapper;
import cn.smile.utils.*;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import jakarta.annotation.Resource;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author smile-jt
 */
@Slf4j
@Service
public class SysUserServiceImpl extends BaseServiceImpl<SysUserMapper, SysUser> implements ISysUserService {
    @Resource
    private IRoleService roleService;
    @Resource
    private IEmailInfoService emailInfoService;
    @Resource
    private RedisUtil redisUtil;
    @Resource
    private IMyShopService shopService;
    @Resource
    private IDicInfoService dicService;
    @Resource
    private IBillBasicItemService basicItemService;

    @Override
    public SysUserDTO queryByLogin(String loginId) {
        log.info("[SysUserServiceImpl].[queryByLogin] ------> 根据登陆ID查询用户信息 Start, loginId = {}", loginId);
        SysUserDTO dto = null;
        if (!ObjectUtils.isEmpty(loginId)) {
            SysUser user = baseMapper.selectOne(new QueryWrapper<SysUser>().lambda().eq(SysUser::getLoginId, loginId));
            if (!ObjectUtils.isEmpty(user)) {
                dto = BeanCopy.copyBean(user, SysUserDTO.class);
                RoleQueryForm form = new RoleQueryForm();
                form.setUserId(dto.getId());
                dto.setRoleList(roleService.queryList(form));
            }
        }
        log.info("[SysUserServiceImpl].[queryByLogin] ------> 根据登陆ID查询用户信息 End, dto = {}", ObjectUtils.isEmpty(dto) ? null : JSON.toJSONString(dto));
        return dto;
    }

    @Override
    public SysUserDTO queryByPhone(String phone) {
        log.info("[SysUserServiceImpl].[queryByPhone] ------> 根据手机号查询用户信息 Start, phone = {}", phone);
        SysUserDTO dto = null;
        if (!ObjectUtils.isEmpty(phone)) {
            SysUser user = baseMapper.selectOne(new QueryWrapper<SysUser>().lambda().eq(SysUser::getPhone, phone).eq(SysUser::getDeleted, Boolean.FALSE));
            if (!ObjectUtils.isEmpty(user)) {
                dto = BeanCopy.copyBean(user, SysUserDTO.class);
            }
        }
        log.info("[SysUserServiceImpl].[queryByLogin] ------> 根据手机号查询用户信息 End, dto = {}", ObjectUtils.isEmpty(dto) ? null : JSON.toJSONString(dto));
        return dto;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateLoginTime(LoginInfoForm form) {
        log.info("[SysUserServiceImpl].[queryByLogin] ------> 更新用户最后登陆信息 Start, form = {}", JSON.toJSONString(form));
        SysUser user = baseMapper.selectOne(new QueryWrapper<SysUser>().lambda().eq(SysUser::getId, form.getId()));
        user.setLastLoginAdd(form.getLastLoginAddress());
        user.setLastLoginTime(LocalDateTime.now());
        super.updateBaseCol(user);
        int updateNum = baseMapper.updateById(user);
        log.info("[SysUserServiceImpl].[queryByLogin] ------> 更新用户最后登陆信息 End, updateNum = {}", updateNum);
        return updateNum > NumberConstant.ZERO;
    }

    @Override
    public IPage<SysUserDTO> queryPage(QueryUserForm form) {
        log.info("[SysUserServiceImpl].[queryPage] ------> 分页查询用户 Start, form = {}", JSON.toJSONString(form));
        LambdaQueryWrapper<SysUser> queryParams = this.getQueryParams(form);
        queryParams.eq(SysUser::getIsShow, Boolean.TRUE);
        Page<SysUser> dataPage = baseMapper.selectPage(form.queryPage(), queryParams);
        IPage<SysUserDTO> resultData = BeanCopy.copyPage(dataPage, SysUserDTO.class);
        this.setUserDetail(resultData.getRecords());
        log.info("[SysUserServiceImpl].[queryPage] ------> 分页查询用户 End");
        return resultData;
    }

    @Override
    public List<SysUserDTO> queryList(QueryUserForm form) {
        log.info("[SysUserServiceImpl].[queryList] ------> 列表查询用户 Start, form = {}", JSON.toJSONString(form));
        List<SysUser> dataPage = baseMapper.selectList(this.getQueryParams(form));
        List<SysUserDTO> result = BeanCopy.copyList(dataPage, SysUserDTO.class);
        log.info("[SysUserServiceImpl].[queryList] ------> 列表查询用户 End");
        return result;
    }

    @Override
    public String encode(String temp) {
        log.info("[SysUserServiceImpl].[encode] ------> 字符串加密 Start, temp = {}", temp);
        String encode = PasswordUtil.encrypt(temp);
        log.info("[SysUserServiceImpl].[encode] ------> 字符串加密 End, encode = {}", encode);
        return encode;
    }

    @Override
    public String randomPwd(Integer length, String email, String receiveName) {
        log.info("[SysUserServiceImpl].[randomPwd] ------> 随机获取强密码, 并发送信息 Start, length = {}, email = {}, receiveName = {}", length, email, receiveName);
        if (ObjectUtils.isEmpty(email)) {
            throw new BusinessException(MyResponseCode.EMAIL_FORMAT_ERROR);
        }
        if (!email.matches(MailConstant.REGU)) {
            throw new BusinessException(MyResponseCode.EMAIL_FORMAT_ERROR);
        }
        //随机密码长度为空或小于 8
        if (ObjectUtils.isEmpty(length) || length < NumberConstant.EIGHT) {
            length = NumberConstant.TWENTY;
        }
        String pwd = PasswordUtil.randomPwd(length);
        ResstPwdMailDTO dto = new ResstPwdMailDTO();
        dto.setPwd(pwd);
        dto.setReceiveName(receiveName);
        emailInfoService.sendMail(MailCodeEnum.RESET_PWD_CODE, JSON.parseObject(JSON.toJSONString(dto), Object.class), email);
        log.info("[SysUserServiceImpl].[randomPwd] ------> 随机获取强密码, 并发送信息 End, pwd = {}", pwd);
        return pwd;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean registUser(HttpServletRequest request, RegistUserForm form) {
        String ip = IpUtils.getRemoteIp(request);
        log.info("请求IP = {}", ip);
        this.checkRegistForm(ip, form);
        return this.registUser(form);
    }

    @SuppressWarnings("SpellCheckingInspection")
    @Override
    public Boolean registUser(RegistUserForm form) {
        log.info("[SysUserServiceImpl].[registUser] ------> 注册用户 Start, form = {}", JSON.toJSONString(form));
        SysUser user = BeanCopy.copyBean(form, SysUser.class);
        user.setPassword(this.encode(form.getPassword()));
        super.addBaseCol(user);
        user.setAvatar(CommonConstant.DEFAULT_AVATAR_URL);
        user.setStatus(UserStatusEnum.ENABLE.getSn());
        user.setUserType(UserTypeEnum.USER.getSn());
        int insertNum = baseMapper.insert(user);
        if (insertNum > NumberConstant.ZERO) {
            Boolean initRole = roleService.initUser(user.getId());
            log.info("关联角色结果: initRole = {}", initRole);
            if (ObjectUtils.isEmpty(form.getShopCode())) {
                String shopCode = shopService.initShop(user.getId());
                form.setShopCode(shopCode);
                log.info("初始化店铺结束, shopCode = {}", shopCode);
            }
            //绑定店铺关系
            Boolean bindShop = shopService.bindShop(user.getId(), form.getShopCode());
            log.info("绑定店铺结束: {}", bindShop);
        }
        log.info("[SysUserServiceImpl].[registUser] ------> 注册用户 End, insertNum = {}", insertNum);
        return insertNum > NumberConstant.ZERO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean forgetPwd(HttpServletRequest request, String loginId) {
        log.info("[SysUserServiceImpl].[forgetPwd] ------> 用户重置密码 Start, loginId = {}", loginId);
        String ip = IpUtils.getRemoteIp(request);
        this.checkForgetNum(ip);
        boolean update = this.resetPassword(loginId);
        log.info("[SysUserServiceImpl].[forgetPwd] ------> 用户重置密码 End, update = {}", update);
        return update;
    }

    @Override
    public Boolean checkLoginId(String loginId) {
        log.info("[SysUserServiceImpl].[checkLoginId] ------> 检查登录ID是否存在 Start, loginId = {}", loginId);
        List<SysUser> dataList = baseMapper.selectList(new QueryWrapper<SysUser>().lambda().eq(SysUser::getDeleted, Boolean.FALSE).eq(SysUser::getLoginId, loginId));
        boolean result = !CollectionUtils.isEmpty(dataList);
        log.info("[SysUserServiceImpl].[checkLoginId] ------> 检查登录ID是否存在 End, result = {}", result);
        return result;
    }

    @Override
    public Boolean checkPhone(String phone) {
        log.info("[SysUserServiceImpl].[checkPhone] ------> 检查手机号是否存在 Start, phone = {}", phone);
        List<SysUser> dataList = baseMapper.selectList(new QueryWrapper<SysUser>().lambda().eq(SysUser::getDeleted, Boolean.FALSE).eq(SysUser::getPhone, phone));
        boolean result = !CollectionUtils.isEmpty(dataList);
        log.info("[SysUserServiceImpl].[checkPhone] ------> 检查手机号是否存在 End, result = {}", result);
        return result;
    }

    @Override
    public void resetTourist() {
        log.info("[SysUserServiceImpl].[resetTourist] ------> 重置游客用户信息 Start");
        SysUser user = this.baseMapper.selectOne(new QueryWrapper<SysUser>().lambda().eq(SysUser::getId, TouristResetConstant.USER_ID).eq(SysUser::getDeleted, Boolean.FALSE));
        if (!ObjectUtils.isEmpty(user)) {
            user.setAvatar(CommonConstant.DEFAULT_AVATAR_URL);
            user.setPhone(TouristResetConstant.PHONE);
            user.setEmail(null);
            user.setNickName(TouristResetConstant.NICK_NAME);
            user.setPassword(TouristResetConstant.PASSWORD);
            super.updateBaseCol(user);
            baseMapper.updateById(user);
        }
        log.info("[SysUserServiceImpl].[resetTourist] ------> 重置游客用户信息 End");
    }

    @Override
    public SysUserDTO getUserInfo() {
        log.info("[SysUserServiceImpl].[getUserInfo] ------> 获取登录用户信息 Start");
        SysUser user = baseMapper.selectOne(new QueryWrapper<SysUser>().lambda().eq(SysUser::getId, UserUtil.getUserInfo().getId()).eq(SysUser::getDeleted, Boolean.FALSE));
        if (ObjectUtils.isEmpty(user)) {
            throw new BusinessException(MyResponseCode.RESULT_DATA_NONE);
        }
        SysUserDTO dto = BeanCopy.copyBean(user, SysUserDTO.class);
        //密码置空
        dto.setPassword(null);
        if (!ObjectUtils.isEmpty(dto.getGender())) {
            dto.setGenderRadioFlag(String.valueOf(dto.getGender()));
        } else {
            dto.setGenderRadioFlag(String.valueOf(NumberConstant.ZERO));
        }
        //店铺信息
        MyShopDTO myShop = shopService.getMyShop();
        if (!ObjectUtils.isEmpty(myShop) && !ObjectUtils.isEmpty(myShop.getShopCode())) {
            String shopName = String.format("%s(%s)", myShop.getShopName(), myShop.getShopCode());
            dto.setShopInfoName(shopName);
        }
        log.info("[SysUserServiceImpl].[getUserInfo] ------> 获取登录用户信息 End");
        return dto;
    }

    @Override
    public Boolean changeAvatar(ChangeAvatarForm form) {
        log.info("[SysUserServiceImpl].[changeAvatar] ------> 更新用户头像 Start, form = {}", JSON.toJSONString(form));
        SysUser entity = baseMapper.selectOne(new QueryWrapper<SysUser>().lambda().eq(SysUser::getDeleted, Boolean.FALSE).eq(SysUser::getId, UserUtil.getUserInfo().getId()));
        if (ObjectUtils.isEmpty(entity)) {
            throw new BusinessException(MyResponseCode.RESULT_DATA_NONE);
        }
        entity.setAvatar(form.getAvatar());
        super.updateBaseCol(entity);
        int updateNum = baseMapper.updateById(entity);
        log.info("[SysUserServiceImpl].[changeAvatar] ------> 更新用户头像 End, updateNum = {}", updateNum);
        return updateNum > NumberConstant.ZERO;
    }

    @Override
    public Boolean updateLoginPwd(UpdatePwdForm form) {
        log.info("[SysUserServiceImpl].[updateLoginPwd] ------> 登陆用户修改密码 Start, form = {}", JSON.toJSONString(form));
        SysUser user = this.checkPwd(form);
        super.updateBaseCol(user);
        int updateNum = baseMapper.updateById(user);
        log.info("[SysUserServiceImpl].[updateLoginPwd] ------> 登陆用户修改密码 End, updateNum = {}", updateNum);
        return updateNum > NumberConstant.ZERO;
    }

    @Override
    public Boolean updateUserBase(UpdateUserBaseForm form) {
        log.info("[SysUserServiceImpl].[updateUserBase] ------> 更新用户基本信息 Start, form = {}", JSON.toJSONString(form));
        SysUser user = baseMapper.selectOne(new QueryWrapper<SysUser>().lambda().eq(SysUser::getDeleted, Boolean.FALSE).eq(SysUser::getId, form.getId()));
        user.setNickName(form.getNickName());
        user.setGender(Integer.parseInt(form.getGenderRadioFlag()));
        user.setEmail(form.getEmail());
        user.setPhone(form.getPhone());
        super.updateBaseCol(user);
        int updateNum = baseMapper.updateById(user);
        log.info("[SysUserServiceImpl].[updateUserBase] ------> 更新用户基本信息 End, updateNum = {}", updateNum);
        return updateNum > NumberConstant.ZERO;
    }

    @Override
    public IPage<SysUserDTO> getMyShopUser(QueryUserForm form) {
        log.info("[SysUserServiceImpl].[getMyShopUser] ------> 查询店铺下绑定的其他用户 Start, form = {}", JSON.toJSONString(form));
        MyShopDTO myShop = shopService.getMyShop();
        Set<String> shopUserIds = new HashSet<>(NumberConstant.ZERO);
        if (ObjectUtils.isEmpty(myShop.getShopCode())) {
            throw new BusinessException(MyResponseCode.SHOP_UN_INIT_ERROR);
        }
        Map<String, Integer> userToDicMap = shopService.getUserIds(myShop.getShopCode());
        if (!userToDicMap.containsKey(myShop.getShopManagerId())) {
            userToDicMap.put(myShop.getShopManagerId(), 1001);
        }
        shopUserIds.addAll(userToDicMap.keySet());
        LambdaQueryWrapper<SysUser> queryParams = this.getQueryParams(form);
        queryParams.eq(SysUser::getIsShow, Boolean.TRUE);
        queryParams.in(SysUser::getId, Lists.newArrayList(shopUserIds));
        Page<SysUser> userPage = baseMapper.selectPage(form.queryPage(), queryParams);
        IPage<SysUserDTO> dataPage = BeanCopy.copyPage(userPage, SysUserDTO.class);
        //写入用户身份信息
        if (!CollectionUtils.isEmpty(dataPage.getRecords())) {
            Map<Integer, DicInfoDTO> dicMap = dicService.getDicMap(PredefinedDicEnum.STAFF_POSITION.getSn());
            List<String> userIds = Lists.newArrayList();
            dataPage.getRecords().forEach(user -> userIds.add(user.getId()));
            //统计用户完成项目及数量
            Map<String, List<BasicItemCountDTO>> userItemCount = Maps.newHashMap();
            if (form.getCountItemNum()){
                userItemCount.putAll(basicItemService.countItemByUser(userIds, form.getCountMonth()));
            }
            for (SysUserDTO entity : dataPage.getRecords()) {
                entity.setPassword(null);
                Integer dicValue = userToDicMap.get(entity.getId());
                entity.setStaffPosition(Lists.newArrayList(String.valueOf(dicValue)));
                if (dicMap.containsKey(dicValue)) {
                    entity.setStaffPositionText(dicMap.get(dicValue).getDicName());
                }
                if (form.getCountItemNum()) {
                    entity.setItemCountList(userItemCount.getOrDefault(entity.getId(), Lists.newArrayList()));
                }
            }
        }
        log.info("[SysUserServiceImpl].[getMyShopUser] ------> 查询店铺下绑定的其他用户 End");
        return dataPage;
    }

    @Override
    public List<SysUserDTO> getMyShopUserList(QueryUserForm form) {
        form.setSize(Integer.MAX_VALUE);
        IPage<SysUserDTO> myShopUser = this.getMyShopUser(form);
        return myShopUser.getRecords();
    }

    @Override
    public Map<String, SysUserDTO> getMyShopUserMap(QueryUserForm form) {
        Map<String, SysUserDTO> userMap = Maps.newHashMap();
        List<SysUserDTO> userList = this.getMyShopUserList(form);
        if (!CollectionUtils.isEmpty(userList)) {
            userList.forEach(sysUserDTO -> userMap.put(sysUserDTO.getId(), sysUserDTO));
        }
        return userMap;
    }

    @Override
    public List<SysUserDTO> getAllEnableUser() {
        log.info("[SysUserServiceImpl].[getAllEnableUser] ------> 查询全部启用账户 Start");
        List<SysUser> baseList = baseMapper.selectList(new QueryWrapper<SysUser>().lambda().eq(SysUser::getDeleted, Boolean.FALSE).eq(SysUser::getStatus, UserStatusEnum.ENABLE.getSn()));
        List<SysUserDTO> dataList = BeanCopy.copyList(baseList, SysUserDTO.class);
        log.info("[SysUserServiceImpl].[getAllEnableUser] ------> 查询全部启用账户 End");
        return dataList;
    }

    /**
     * 检查密码
     *
     * @param form 检查参数
     */
    private SysUser checkPwd(UpdatePwdForm form) {
        if (!form.getNewPwd().equals(form.getConfirmPwd())) {
            throw new BusinessException(MyResponseCode.CONFIRM_PASSWORD_ERROR);
        }
        if (form.getNewPwd().equals(form.getOldPwd())) {
            throw new BusinessException(MyResponseCode.NO_CHANGE_PASSWORD_ERROR);
        }
        SysUser user = baseMapper.selectOne(new QueryWrapper<SysUser>().lambda().eq(SysUser::getId, UserUtil.getUserInfo().getId()).eq(SysUser::getDeleted, Boolean.FALSE));
        if (ObjectUtils.isEmpty(user)) {
            throw new BusinessException(MyResponseCode.RESULT_DATA_NONE);
        }
        String oldEncode = this.encode(form.getOldPwd());
        if (!oldEncode.equals(user.getPassword())) {
            throw new BusinessException(MyResponseCode.OLD_PASSWORD_ERROR);
        }
        user.setPassword(this.encode(form.getNewPwd()));
        return user;
    }

    /**
     * 写入用户详情信息
     *
     * @param dataList 用户集合
     */
    private void setUserDetail(List<SysUserDTO> dataList) {
        if (!CollectionUtils.isEmpty(dataList)) {
            List<String> userIds = dataList.stream().map(SysUserDTO::getId).collect(Collectors.toList());
            Map<String, Set<String>> roleCodeMap = roleService.getRoleCodeMap(userIds);
            for (SysUserDTO user : dataList) {
                user.setRoleCodes(Lists.newArrayList(roleCodeMap.getOrDefault(user.getId(), new HashSet<>())));
                user.setGenderText(UserSexEnum.get(user.getGender()).getMsg());
                user.setStatusText(UserStatusEnum.get(user.getStatus()).getMsg());
            }
        }
    }

    /**
     * 获取列表查询参数
     *
     * @param form 查询参数
     * @return 查询对象
     */
    private LambdaQueryWrapper<SysUser> getQueryParams(QueryUserForm form) {
        LambdaQueryWrapper<SysUser> qw = new QueryWrapper<SysUser>().lambda().eq(SysUser::getDeleted, Boolean.FALSE);
        if (!ObjectUtils.isEmpty(form.getNickName())) {
            qw.like(SysUser::getNickName, form.getNickName());
        }
        if (!CollectionUtils.isEmpty(form.getIds())) {
            qw.in(SysUser::getId, form.getIds());
        }
        return qw;
    }

    /**
     * 验证注册参数
     *
     * @param ip   IP
     * @param form 请求参数
     */
    private void checkRegistForm(String ip, RegistUserForm form) {
        Object bucket = redisUtil.get(String.format(RedisKeyConstant.USER_REGISTER_KEY, ip));
        RegistRedisDTO registNum;
        //验证接口请求次数是否两小时达到5次
        if (!ObjectUtils.isEmpty(bucket)) {
            registNum = JSON.parseObject(bucket.toString(), RegistRedisDTO.class);
            if (NumberConstant.FIVES == registNum.getNum()) {
                throw new BusinessException(MyResponseCode.REGIST_USER_ERROR);
            }
        } else {
            registNum = new RegistRedisDTO();
            registNum.setNum(NumberConstant.ZERO);
        }
        //注册, 请求次数+1
        registNum.setNum(registNum.getNum() + NumberConstant.ONE);
        redisUtil.set(String.format(RedisKeyConstant.USER_REGISTER_KEY, ip), JSON.toJSONString(registNum), RedisKeyConstant.USER_REGISTER_TIMEOUT);
        //验证手机号是否存在
        if (this.checkPhone(form.getPhone())) {
            throw new BusinessException(MyResponseCode.PHONE_EXIST_ERROR);
        }
        //未填写用户昵称, 写入默认用户名
        if (ObjectUtils.isEmpty(form.getNickName())) {
            form.setNickName(String.format(CommonConstant.DEFAULT_NICK_NAME, PasswordUtil.randomLoginId(NumberConstant.FOUR)));
        }
        //无登录ID, 默认
        if (ObjectUtils.isEmpty(form.getLoginId())) {
            form.setLoginId(this.randomLoginId());
        }
    }

    /**
     * 随机一个8位, 数据库没有的登录ID
     *
     * @return 随机的登录ID
     */
    private String randomLoginId() {
        String loginId = PasswordUtil.randomLoginId(NumberConstant.EIGHT);
        if (this.checkLoginId(loginId)) {
            loginId = this.randomLoginId();
        }
        return loginId;
    }

    /**
     * 检查忘记密码参数
     *
     * @param ip 访问ID
     */
    private void checkForgetNum(String ip) {
        Object bucket = redisUtil.get(String.format(RedisKeyConstant.USER_FORGET_PWD_KEY, ip));
        ForgetRedisDTO forgetNum;
        //验证接口请求次数是否两小时达到5次
        if (!ObjectUtils.isEmpty(bucket)) {
            forgetNum = JSON.parseObject(bucket.toString(), ForgetRedisDTO.class);
            if (NumberConstant.FIVES == forgetNum.getNum()) {
                throw new BusinessException(MyResponseCode.RESET_PWD_ERROR);
            }
        } else {
            forgetNum = new ForgetRedisDTO();
            forgetNum.setNum(NumberConstant.ZERO);
        }
        //重置, 请求次数+1
        forgetNum.setNum(forgetNum.getNum() + NumberConstant.ONE);
        redisUtil.set(String.format(RedisKeyConstant.USER_FORGET_PWD_KEY, ip), JSON.toJSONString(forgetNum), RedisKeyConstant.USER_FORGET_PWD_TIMEOUT);
    }

    /**
     * 重置用户密码
     *
     * @param loginId 登录名
     * @return 重置密码结果
     */
    private boolean resetPassword(String loginId) {
        SysUserDTO dto = this.queryByLogin(loginId);
        if (ObjectUtils.isEmpty(dto)) {
            throw new BusinessException(MyResponseCode.USER_DATA_NONE);
        }
        if (ObjectUtils.isEmpty(dto.getEmail())) {
            throw new BusinessException(MyResponseCode.UNBOUNDED_EMAIL_NONE);
        }
        String newPwd = this.randomPwd(NumberConstant.TWENTY, dto.getEmail(), dto.getNickName());
        dto.setPassword(this.encode(newPwd));
        super.updateBaseCol(dto);
        return super.update(dto);
    }
}